﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using HeritageAcademy.Models.DataModels;
using HeritageAcademy.Shared;

namespace HeritageAcademy.Models.ViewModels
{
    public class ChapterViewModel : ViewModelBase<Chapter>
    {
        #region Parameters 
        
        private CourseViewModel _book;

        /// <summary>
        /// The backing field for the Chapters property
        /// </summary>
        private ChapterViewModelCollection _chapters;

        /// <summary>
        /// A bool that indicates whether the current chapter is actively being 
        /// viewed in the UI. There should only be one chapter that is current at
        /// any given time and that is enforced in the SetCurrentChapter method of
        /// the BookViewModel object.
        /// </summary>
        private bool _isCurrent;
        
        #endregion

        #region Ctor
        
        /// <summary>
        /// An internal constructor for the ChapterViewModel class. This 
        /// constructor is internal because it should only ever be created by
        /// the BookViewModel class.
        /// </summary>
        public ChapterViewModel(Chapter chapter, CourseViewModel book) : base(chapter)
        {
            Book = book;
            UpdateChapters();
        }
        
        #endregion

        #region Properties 
        private int? _currentPageNumber;

        public CourseViewModel Book
        {
            get { return _book; }
            set
            {
                _book = value;
                RaisePropertyChanged("Book");
            }
        }

        public ChapterViewModelCollection Chapters
        {
            get { return _chapters; }
            set
            {
                _chapters = value;
                RaisePropertyChanged("Chapters");
            }
        }

        /// <summary>
        /// Chapter formated as FlowDocument object.
        /// </summary>
        public FlowDocument Document
        {
            get
            {
                var b = Book.Model;

                if (b != null)
                {
                    var s = b.GetChapterContent(Model.Index);

                    DocumentLength = s.Length + 1500;
                    IsDocumentLengthValid = true;

                    var f = XamlReader.Parse(s) as FlowDocument;
                    if (f != null) return f;
                }
                
                return null;
            }
        }

        public int DocumentLength { get; private set; }
        public bool IsDocumentLengthValid { get; private set; }

        public bool IsCurrent
        {
            get { return _isCurrent; }
            internal set
            {
                if (_isCurrent == value) return;
                _isCurrent = value;
                RaisePropertyChanged("IsCurrent");
            }
        }

        public int? CurrentPageNumber
        {
            get { return _currentPageNumber; }
            set
            {
                // this property is updated by the owning BookViewModel
                _currentPageNumber = value;
                RaisePropertyChanged("CurrentPageNumber");
            }
        }
        #endregion Properties 

        #region Private Methods 
        
        /// <summary>
        /// Generates ViewModels for each of the ChapterGroups associated with 
        /// the book object that this ViewModel wraps
        /// </summary>
        private void UpdateChapters()
        {
            Chapters = new ChapterViewModelCollection();

            foreach (var chm in Model.Chapters.Select(ch => new ChapterViewModel(ch, Book)))
                Chapters.Add(chm);
        }
        
        #endregion Private Methods 

        #region GotoChapterCommand
        private RelayCommand _gotoChapterCommand;

        public ICommand GotoChapterCommand
        {
            get
            {
                return _gotoChapterCommand ?? (_gotoChapterCommand = new RelayCommand(param => GotoChapter(),
                                                                                      param => CanGotoChapter()));
            }
        }

        private void GotoChapter()
        {
            if (Book != null)
                Book.CurrentLocation = new CourseLocation(Book.FlatChapters.IndexOf(this), 0);
        }

        private bool CanGotoChapter()
        {
            return Book.FlatChapters.Contains(this);
        }
        #endregion
    }

    public class ChapterViewModelCollection : ObservableCollection<ChapterViewModel>
    {
    }
}